package com.siqi.hr.system.custom.controller;

import com.siqi.hr.common.utils.Const;
import com.siqi.hr.system.common.enums.OperationEnum;
import com.siqi.hr.system.common.model.filter.QueryDataEntity;
import com.siqi.hr.system.common.utils.QueryDataUtil;
import com.siqi.hr.system.custom.entity.EntityOperation;
import com.siqi.hr.system.custom.entity.EntityRecord;
import com.siqi.hr.system.custom.entity.FieldRecord;
import com.siqi.hr.system.custom.entity.SelectBox;
import com.siqi.hr.system.custom.service.EntityRecordService;
import com.siqi.hr.system.custom.service.FieldRecordService;
import com.siqi.hr.system.custom.service.QueryService;
import com.siqi.hr.system.custom.service.SelectBoxService;
import com.siqi.hr.system.organization.entity.Employee;
import com.siqi.hr.system.organization.entity.FieldControled;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 实体注册字段控制层
 * @author    xiaogq
 * Created by xiaogoingqin on 2016/7/24.
 */
@Controller
@RequestMapping("FieldRecord")
public class FieldRecordController {
    private static final Logger logger = Logger.getLogger(FieldRecordController.class);

    @Autowired
    private EntityRecordService entityRecordService;

    @Autowired
    private FieldRecordService fieldRecordService;

    @Autowired
    private QueryService queryService;

    @Autowired
    private SelectBoxService selectBoxService;

    /**
     * 实体属性设置列表页(xiaogq)
     * @param request
     * @param entityId      实体Id
     * @return
     */
    @RequestMapping(value = "fieldRecordListInit", method = RequestMethod.GET)
    public ModelAndView fieldRecordListInit(HttpServletRequest request, Integer entityId) throws Exception{
        Map<String,Object> columnMap = fieldRecordService.queryFieldLayoutListColumns();
        EntityRecord er = entityRecordService.queryEntityRecordById(entityId);
        List<EntityOperation> listButtons = new ArrayList<EntityOperation>();
        if(er.getDefineField()){
            EntityOperation addField = new EntityOperation("新建","addField","FieldRecord/fieldRecordAddInit.do","image/common/operation/oper_ADD.png", OperationEnum.showList.name(),new EntityRecord(0));
            listButtons.add(addField);
        }
        EntityOperation sortField = new EntityOperation("排序","sortFields","FieldRecord/fieldSort.do","image/common/operation/oper_sort.png",OperationEnum.showList.name(),new EntityRecord(0));
        listButtons.add(sortField);
        ModelAndView andView = new ModelAndView();
        andView.addObject("listButtons",listButtons);
        andView.addObject("columns", columnMap.get("columns"));
        andView.addObject("entity", er);
        andView.setViewName("system/custom/field/field_list");
        return andView;
    }

    /**
     * 根据实体id查询当前实体的系统属性或者自定义属性
     * @author        xiaogq
     * @param request
     * @param entityId      实体id
     * @param sysField      是否系统属性标识(1[true]:是，0[false]:否)
     * @return
     * @throws Exception
     */
    @RequestMapping("queryFieldList")
    @ResponseBody
    public Map<String, Object> queryFieldList(HttpServletRequest request,Integer entityId, Boolean sysField) throws Exception {
        //获取搜索条件、当前登录用户、部门以及分页数据信息
        QueryDataEntity queryData = QueryDataUtil.getQueryDataEntity(request);
        queryData.setTableCode(entityId);
        return fieldRecordService.queryEntityData(queryData, sysField);
    }

    /**
     * 初始化字段添加页面
     * @author        xiaogq
     * @param request
     * @param entityId    实体Id
     * @param title        实体中午名称
     * @return
     */
    @RequestMapping(value = "fieldRecordAddInit", method = RequestMethod.GET)
    public ModelAndView fieldRecordAddInit(HttpServletRequest request,Integer entityId,String title) throws Exception{
        //根据实体Id获得实体信息
        ModelAndView andView = new ModelAndView();
        andView.addObject("entityId", entityId);
        andView.addObject("title", title);
        //判断实体是否是明细实体
        andView.setViewName("system/custom/field/field_add_init");

        return andView;
    }

    /**
     * 新建具体类型字段方法(xiaogq)
     * @param request
     * @param entityId        实体id
     * @param fieldTypeId     具体字段类型(1:数值、2:百分比、3:货币、4:字符串、5:电子邮件、6:网址、7:文本域、8:长文本区域、9:引用、10:电话、11:下拉框、
     * 12:下拉框(多选)、13:日期、14:日期时间、15:自动编号、16:复选框、17:单选框、18:图片，19:身份证号,20:银行卡号)
     * @return
     */
    @RequestMapping(value = "fieldRecordAdd", method = RequestMethod.GET)
    public ModelAndView fieldRecordAdd(HttpServletRequest request,Integer entityId, Integer fieldTypeId) {
        List<EntityRecord> ers = null;
        //如果是引用字段
        if (fieldTypeId == 9) {
            //查询所有可以被引用实体的id及中文名称
            ers = this.entityRecordService.getCanQuoteEntity(true);
        }
        List<FieldRecord> frs = null;
        //如果是单选、下拉、下拉多选
        if (fieldTypeId == 11 || fieldTypeId == 12 || fieldTypeId == 17) {
            //新建的是单选、下拉、下拉多选类型的字段则查询字段注册表中所有的该类型字段信息
            frs = this.fieldRecordService.getAllBoxFields();
        }
        ModelAndView andView = new ModelAndView();
        andView.addObject("entityId", entityId);
        andView.addObject("frs", frs);
        andView.addObject("fieldTypeId", fieldTypeId);
        andView.addObject("canQuoteEntity", ers);
        andView.addObject("entityLocalization",request.getParameter("entityLocalization"));
        andView.setViewName("system/custom/field/field_add");
        return andView;
    }

    /**
     * 添加自定义字段时验证字段英文名是否重复
     * @author                  xiaogq
     * @param entityId        实体id
     * @param fieldTypeId     具体字段类型(1:数值、2:百分比、3:货币、4:字符串、5:电子邮件、6:网址、7:文本域、8:长文本区域、9:引用、10:电话、11:下拉框、
     * 12:下拉框(多选)、13:日期、14:日期时间、15:自动编号、16:复选框、17:单选框、18:图片)
     * @return
     */
    @RequestMapping(value = "validateFieldName", method = RequestMethod.POST)
    @ResponseBody
    Map<String, Object> validateFieldName(String fieldName, Integer entityId,Integer fieldTypeId) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("value", false);
        if (fieldTypeId == null || fieldTypeId == 9){
            return map;
        }
        return fieldRecordService.validateFieldName(fieldName, entityId,fieldTypeId);
    }

    /**
     * 保存(新建)自定义字段
     * @author                  xiaogq
     * @param request
     * @param fieldRecord    字段信息
     * @return
     */
    @RequestMapping(value = "fieldRecordSave", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> fieldRecordSave(HttpServletRequest request,FieldRecord fieldRecord) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("success", true);
        //添加自定义字段
        fieldRecordService.addFieldRecord(fieldRecord, null);
        return map;
    }

    /**
     * 初始化注册字段编辑页面
     * @author                  xiaogq
     * @param request
     * @param fieldId     注册字段Id
     * @return
     */
    @RequestMapping(value = "fieldRecordEditInit", method = RequestMethod.GET)
    public ModelAndView fieldRecordEditInit(HttpServletRequest request,int fieldId) {
        //根据字段Id查询注册字段所有信息
        FieldRecord field = fieldRecordService.getFieldRecord(fieldId);
        //得到字段英文名
        String fname = field.getName();
        //根据注册字段英文名称后缀得到对应的数字
        int fieldType = fieldRecordService.getFieldType(fname);
        ModelAndView andView = new ModelAndView();
        andView.addObject("field", field);
        andView.addObject("fieldTypeId", fieldType);
        andView.setViewName("system/custom/field/field_edit");
        return andView;
    }

    /**
     * 保存编辑字段信息
     * @param request
     * @param fieldRecord    需编辑的字段信息对象
     * @throws Exception
     */
    @RequestMapping(value = "fieldRecordUpdate", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> fieldRecordUpdate(HttpServletRequest request,FieldRecord fieldRecord) throws Exception {
        Map<String, Object> resultMap = fieldRecordService.updateFieldRecord(fieldRecord);
        return resultMap;
    }

    /**
     * 初始化字段排序页面
     * @author        xiaogq
     * @param request
     * @param entityId
     * @return
     */
    @RequestMapping(value = "fieldSort", method = RequestMethod.GET)
    public ModelAndView fieldSort(HttpServletRequest request, int entityId) {
        //根据实体id查询该实体所有的字段(系统字段与自定义字段)
        List<FieldRecord> fields = fieldRecordService.getAllFields(entityId);
        ModelAndView andView = new ModelAndView();
        andView.addObject("entityId", entityId);
        andView.addObject("fields", fields);
        andView.setViewName("system/custom/field/field_sort");
        return andView;
    }

    /**
     * 保存实体字段排序
     * @author        xiaogq
     * @param         sortIds     字段id字符串
     * @return
     * @throws IOException
     */
    @RequestMapping("fieldSortUpdate")
    @ResponseBody
    public JSONObject fieldSortUpdate(String sortIds) throws IOException {
        JSONObject obj = new JSONObject();
        int nums = this.fieldRecordService.fieldSortUpdate(sortIds);
        if(nums > 0){
            obj.put("results","sucess");
        }else{
            obj.put("results","error");
        }
        return obj;
    }

    /**
     * 根据注册字段id删除自定义字段
     * @author        xiaogq
     * @param fieldId
     * @return
     * @throws Exception
     */
    @RequestMapping("fieldRecordDelete")
    @ResponseBody
    public JSONObject fieldRecordDelete(Integer fieldId) throws Exception {
        JSONObject obj = new JSONObject();
        FieldRecord f = fieldRecordService.getFieldRecord(fieldId);
        String fieldName = f.getName();
        Integer tableCode = f.getEntityRecord().getTableCode();
        //查询当前库中实体表字段是否存在
        boolean fexist = fieldRecordService.checkedFieldIsExist(fieldName,tableCode);
        if (fexist) {
            //查询当前枚举字段值是否在实体表中被引用
            boolean dexist = fieldRecordService.checkedFieldHasData(fieldName, tableCode);
            if (!dexist) {//如果该枚举字段值在实体表中还未被引用则删除
                fieldRecordService.fieldRecordDelete(f);
            }
            obj.put("hasData", dexist);

            queryService.removeFieldFromCondition(tableCode, fieldName);
        }
        return obj;
    }

    /**
     * 属性级控制
     * @author        xiaogq
     * @param request
     * @param entityId     实体id
     * @param fieldId      字段id
     * @param fieldName    字段名称
     * @return
     */
    @RequestMapping("fieldControlList")
    public ModelAndView fieldControlList(HttpServletRequest request, Integer entityId, Integer fieldId,String fieldName) {
        List<FieldControled> authList = fieldRecordService.getFieldControledList(entityId,fieldId);

        ModelAndView mav = new ModelAndView();
        mav.addObject("authList", authList);
        mav.addObject("entityId", entityId);
        mav.addObject("fieldId", fieldId);
        mav.addObject("fieldName", fieldName);
        mav.setViewName("system/custom/field/field_control_list");
        return mav;
    }

    /**
     * 字段级权限设置保存方法
     * @author        xiaogq
     * @param request
     * @param entityId     实体id
     * @param fieldId      字段id
     * @param fieldName    字段名称
     * @param authArr      角色字段权限参数
     * @return
     */
    @RequestMapping(value = "saveFieldControl", method = RequestMethod.POST)
    public void saveFieldControl(HttpServletRequest request, Integer entityId, Integer fieldId,String fieldName, String[] authArr) {
        fieldRecordService.saveFieldControled(entityId, fieldId,fieldName, authArr);
    }

    /**
     * 初始化单选、下拉、下拉多选页面
     * @author             xiaogq
     * @param request
     * @param fieldId     注册字段id
     * @param entityId    实体id
     * @return
     */
    @RequestMapping(value = "fieldSelectBoxlist", method = RequestMethod.GET)
    public ModelAndView fieldSelectBoxlist(HttpServletRequest request,int fieldId, Integer entityId) {
        //单选、下拉、下拉多选列表页表头信息
        Map<String,Object> columnMap = selectBoxService.querySelectBoxListColumns();
        ModelAndView andView = new ModelAndView();
        andView.addObject("fieldId", fieldId);
        andView.addObject("entityId", entityId);
        andView.addObject("columns", columnMap.get("columns"));
        andView.addObject("fields", columnMap.get("fields"));
        andView.setViewName("system/custom/selectbox/selectbox_list");
        return andView;
    }

    /**
     * 根据字段id查询单选、下拉、下拉多选类型字段所有枚举值信息
     * @author             xiaogq
     * @param request
     * @param fieldId     注册字段id
     * @return
     * @throws Exception
     */
    @RequestMapping("queryFieldSelectBoxList")
    @ResponseBody
    public Map<String, Object> queryFieldSelectBoxList(HttpServletRequest request,Integer fieldId) throws Exception {
        //根据字段id查询单选、下拉、下拉多选类型字段所有枚举值信息
        Map<String,Object> dataMap = selectBoxService.queryEntityData(fieldId);
        logger.debug(dataMap);
        return dataMap;
    }

    /**
     * 新建单选、下拉、下拉多选类型字段枚举值页面
     * @param request
     * @param entityId     实体id
     * @param fieldId      注册字段id
     * @return
     */
    @RequestMapping(value = "selectBoxAddInit", method = RequestMethod.GET)
    public ModelAndView selectBoxAddInit(HttpServletRequest request,int entityId,int fieldId) {
        ModelAndView andView = new ModelAndView();
        andView.addObject("entityId", entityId);
        andView.addObject("fieldId", fieldId);
        andView.setViewName("system/custom/selectbox/selectbox_add");
        return andView;
    }

    /**
     * 保存单选、下拉、下拉多选类型字段枚举值信息
     * @author             xiaogq
     * @param selectBox
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "selectBoxSave", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> selectBoxSave(SelectBox selectBox) throws IOException {
        Map<String, Object> resultMap = new HashMap<String,Object>();
        int nums = selectBoxService.addSelectBox(selectBox);
        if (nums > 0){
            resultMap.put("results","sucess");
        }else{
            resultMap.put("results","error");
        }
        return resultMap;
    }

    /**
     * 根据枚举id编辑枚举信息
     * @author             xiaogq
     * @param request
     * @param selectBoxId   枚举id
     * @return
     */
    @RequestMapping(value = "selectBoxEdit", method = RequestMethod.GET)
    public ModelAndView selectBoxEdit(HttpServletRequest request,int selectBoxId) {
        //根据枚举值id获取枚举对象信息
        SelectBox sb = selectBoxService.getSelectBox(selectBoxId);
        ModelAndView andView = new ModelAndView();
        andView.addObject("sb", sb);
        andView.setViewName("system/custom/selectbox/selectbox_edit");
        return andView;
    }

    /**
     * 保存编辑枚举型字段
     * @author             xiaogq
     * @param selectBox    枚举值对象信息
     * @throws Exception
     */
    @RequestMapping(value = "selectBoxUpdate", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> selectBoxUpdate(SelectBox selectBox) throws Exception {
        //保存编辑枚举型字段
        Map<String, Object> resultMap = selectBoxService.updateSelectBox(selectBox);
        return resultMap;
    }

    /**
     * 枚举字段排序
     * @author             xiaogq
     * @param request
     * @param fieldId   注册字段id
     * @return
     */
    @RequestMapping(value = "selectBoxSort", method = RequestMethod.GET)
    public ModelAndView selectBoxSort(HttpServletRequest request, int fieldId) {
        List<SelectBox> sbs = selectBoxService.getAllSelectBoxByFieldId(fieldId,"");
        ModelAndView andView = new ModelAndView();
        andView.addObject("fieldId", fieldId);
        andView.addObject("sbs", sbs);
        andView.setViewName("system/custom/selectbox/selectbox_sort");
        return andView;
    }

    /**
     * 保存枚举排序方法
     * @author             xiaogq
     * @param sortIds     所有排序枚举值id
     * @return
     * @throws IOException
     */
    @RequestMapping("selectBoxSortUpdate")
    @ResponseBody
    public JSONObject selectBoxSortUpdate(String sortIds) throws IOException {
        JSONObject resultObj = selectBoxService.selectBoxSortUpdate(sortIds);
        return resultObj;
    }

    /**
     * 根据枚举id删除枚举字段
     * @author                 xiaogq
     * @param selectBoxId   枚举值id
     * @throws Exception
     */
    @RequestMapping("fieldRecordEnumValueDelete")
    @ResponseBody
    public Map<String, Object> fieldRecordEnumValueDelete(Integer selectBoxId) throws Exception {
        Map<String,Object> map = selectBoxService.deleteSelectBox(selectBoxId);
        return map;
    }

    /**
     * 如果是下拉类型的字段定义约束关系方法
     * @author                      xiaogq
     * @param request
     * @param entityId             实体id
     * @param fieldId              注册字段id
     * @return
     */
    @RequestMapping("fieldRestrictedList")
    public ModelAndView fieldRestrictedList(HttpServletRequest request, Integer entityId, Integer fieldId) {
        List<FieldRecord> fieldList = fieldRecordService.getFieldRestrictedList(entityId, fieldId);
        Integer restricterId = fieldRecordService.getFieldRestricter(fieldId);
        ModelAndView mav = new ModelAndView();
        mav.addObject("fieldList", fieldList);
        mav.addObject("entityId", entityId);
        mav.addObject("fieldId", fieldId);
        mav.addObject("restricterId", restricterId);
        mav.setViewName("system/custom/field/field_restrict_list");
        return mav;
    }

    /**
     * 枚举值定义约束关系保存方法方法
     * @author                      xiaogq
     * @param request
     * @param entityId             实体id
     * @param fieldId              注册字段id
     * @param resFieldId          新约束关系字段id
     * @param pidresFieldId      原约束关系字段id
     * @return
     */
    @RequestMapping(value = "saveFieldRestricted", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, String> saveFieldRestricted(HttpServletRequest request, Integer entityId, Integer fieldId,Integer resFieldId, Integer pidresFieldId) {
        Employee emp = (Employee) request.getSession().getAttribute("emp");
        Map<String, String> map = new HashMap<String, String>();
        if (resFieldId != null && resFieldId != 0) {
            Integer resId = fieldRecordService.getFieldRestricter(resFieldId);
            if (resId.equals(fieldId)) {
                map.put("error", "不能循环定义约束关系!");
                return map;
            }
        }
        int lens = fieldRecordService.saveFieldRestricted(entityId, fieldId,resFieldId, pidresFieldId);
        if(lens > 0){
            map.put("error", "success");
        }else{
            map.put("error", "error");
        }
        return map;
    }

    /**
     * 枚举控制属性设置方法
     * @author                   xiaogq
     * @param entityId         实体id
     * @param fieldId          注册字段id
     * @param fieldLocal       被控制属性名称
     * @param resFieldId       控制字段id
     * @param resFieldLocal    控制属性中文名称
     * @return
     */
    @RequestMapping("fieldRestrictedSet")
    public ModelAndView fieldRestrictedSet(HttpServletRequest request, Integer entityId, Integer fieldId,String fieldLocal, Integer resFieldId, String resFieldLocal) {
        ModelAndView mav = new ModelAndView();
        mav.addObject("entityId", entityId);
        mav.addObject("fieldId", fieldId);
        mav.addObject("fieldLocal", fieldLocal);
        mav.addObject("resFieldId", resFieldId);
        mav.addObject("resFieldLocal", resFieldLocal);
        mav.setViewName("system/custom/field/field_restrict_set");
        return mav;
    }

    /**
     * 查询枚举值定义约束关系列表数据
     * @author                   xiaogq
     * @param request
     * @param fieldId       被约束字段id
     * @param resFieldId    约束字段id
     * @return
     */
    @RequestMapping("queryRestrictFields")
    @ResponseBody
    public Map<String, Object> queryRestrictFields(HttpServletRequest request, Integer fieldId, Integer resFieldId) {
        List<Map<String, Object>> list = fieldRecordService.queryRestrictFields(fieldId,resFieldId);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put(Const.TOTAL, list.size());
        resultMap.put(Const.ROWS, list);
        return resultMap;
    }

    /**
     * 设置(编辑)属性级控制
     * @author                  xiaogq
     * @param fieldId          被约束字段id
     * @param fieldLocal       被约束字段名称
     * @param resFieldId       约束字段id
     * @param resOptionId      枚举值id
     * @param resOptionName    枚举值名称
     * @return
     */
    @RequestMapping("fieldRestrictedEdit")
    public ModelAndView fieldRestrictedEdit(HttpServletRequest request, Integer fieldId, String fieldLocal,Integer resFieldId, Integer resOptionId, String resOptionName) {
        //根据字段id查询所有的枚举值
        List<SelectBox> fieldList = selectBoxService.getAllSelectBoxByFieldId(fieldId,"");
        //根据字段id、枚举值id查询约束关系对于的枚举值
        List<SelectBox> showList = fieldRecordService.getRestrictShowFields(fieldId,resOptionId);

        List<Integer> showIdList = new ArrayList<Integer>();
        for (SelectBox showbox : showList) {
            showIdList.add(showbox.getId());
        }

        List<SelectBox> hideList = new ArrayList<SelectBox>();
        for (SelectBox sel : fieldList) {
            if (!showIdList.contains(sel.getId())) {
                hideList.add(sel);
            }
        }

        ModelAndView mav = new ModelAndView();
        mav.addObject("fieldId", fieldId);
        mav.addObject("fieldLocal", fieldLocal);
        mav.addObject("resFieldId", resFieldId);
        mav.addObject("resOptionId", resOptionId);
        mav.addObject("resOptionName", resOptionName);
        mav.addObject("showList", showList);
        mav.addObject("hideList", hideList);
        mav.setViewName("system/custom/field/field_restrict_edit");
        return mav;
    }

    /**
     * 保存(编辑)属性级控制
     * @author                  xiaogq
     * @param fieldId          被约束字段id
     * @param resFieldId       约束字段id
     * @param resOptionId      枚举值id
     * @param resOptionName    枚举值名称
     * @return
     */
    @RequestMapping("saveFieldRestrictedEdit")
    @ResponseBody
    public JSONObject saveFieldRestrictedEdit(HttpServletRequest request,Integer fieldId, Integer resFieldId,Integer resOptionId, String resOptionName) {
        JSONObject obj = new JSONObject();
        //获取约束关系字段信息字符串
        String sortFields = request.getParameter("sortOptions").toString();
        List<SelectBox> optionList = new ArrayList<SelectBox>();
        if (StringUtils.isNotEmpty(sortFields)) {
            JSONArray json = JSONArray.fromObject(sortFields);
            optionList = (List<SelectBox>) JSONArray.toCollection(json, SelectBox.class);
        }

        int lens = fieldRecordService.setRestrictShowFields(fieldId, optionList,resFieldId, resOptionId, resOptionName);
        obj.put("flag",lens > 0);
        return obj;
    }

}
